#
# Copyright (c) 2024 Black Sesame Technologies
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import sys

from dalidl_generator_cpp import generate_cpp_from_dict as dalidl_generator_cpp_gen
from dalidl_typesupport_cpp import generate_cpp_from_dict as dalidl_typesupport_cpp_gen
from dalidl_typesupport_fastrtps_cpp import generate_cpp_from_dict as dalidl_typesupport_fastrtps_cpp_gen
from dalidl_typesupport_introspection_cpp import generate_cpp_from_dict as dalidl_typesupport_introspection_cpp_gen

from path_helper import update_path
from path_helper import check_directory

arg_typesupports = ['dalidl_typesupport_fastrtps_cpp', 'dalidl_typesupport_introspection_cpp']

dalidl_generator_cpp_arg_dict = {
	"package_name": "${PKG_NAME}",
	"output_dir": "${CURRENT_DIR}/build/${PKG_NAME}/dalidl_generator_cpp/${PKG_NAME}",
	"template_dir": "${CURRENT_DIR}/resource/dalidl_generator_cpp",
	"idl_tuples": [],
	"target_dependencies": [
		"${CURRENT_DIR}/resource/dalidl_generator_cpp/action__builder.hpp.em",
		"${CURRENT_DIR}/resource/dalidl_generator_cpp/action__struct.hpp.em",
		"${CURRENT_DIR}/resource/dalidl_generator_cpp/action__traits.hpp.em",
		"${CURRENT_DIR}/resource/dalidl_generator_cpp/idl.hpp.em",
		"${CURRENT_DIR}/resource/dalidl_generator_cpp/idl__builder.hpp.em",
		"${CURRENT_DIR}/resource/dalidl_generator_cpp/idl__struct.hpp.em",
		"${CURRENT_DIR}/resource/dalidl_generator_cpp/idl__traits.hpp.em",
		"${CURRENT_DIR}/resource/dalidl_generator_cpp/msg__builder.hpp.em",
		"${CURRENT_DIR}/resource/dalidl_generator_cpp/msg__struct.hpp.em",
		"${CURRENT_DIR}/resource/dalidl_generator_cpp/msg__traits.hpp.em",
		"${CURRENT_DIR}/resource/dalidl_generator_cpp/srv__builder.hpp.em",
		"${CURRENT_DIR}/resource/dalidl_generator_cpp/srv__struct.hpp.em",
		"${CURRENT_DIR}/resource/dalidl_generator_cpp/srv__traits.hpp.em",
	]
}

dalidl_typesupport_cpp_arg_dict = {
    "package_name": "${PKG_NAME}",
    "output_dir": "${CURRENT_DIR}/build/${PKG_NAME}/dalidl_typesupport_cpp/${PKG_NAME}",
    "template_dir": "${CURRENT_DIR}/resource/dalidl_typesupport_cpp",
    "idl_tuples": [],
    "target_dependencies": [
        "${CURRENT_DIR}/resource/dalidl_typesupport_cpp/action__type_support.cpp.em",
        "${CURRENT_DIR}/resource/dalidl_typesupport_cpp/idl__type_support.cpp.em",
        "${CURRENT_DIR}/resource/dalidl_typesupport_cpp/msg__type_support.cpp.em",
        "${CURRENT_DIR}/resource/dalidl_typesupport_cpp/srv__type_support.cpp.em",
    ]
}

dalidl_typesupport_fastrtps_cpp_arg_dict = {
    "package_name": "${PKG_NAME}",
    "output_dir": "${CURRENT_DIR}/build/${PKG_NAME}/dalidl_typesupport_fastrtps_cpp/${PKG_NAME}",
    "template_dir": "${CURRENT_DIR}/resource/dalidl_typesupport_fastrtps_cpp",
    "idl_tuples": [],
    "target_dependencies": [
        "${CURRENT_DIR}/resource/dalidl_typesupport_fastrtps_cpp/idl__dalidl_typesupport_fastrtps_cpp.hpp.em",
        "${CURRENT_DIR}/resource/dalidl_typesupport_fastrtps_cpp/idl__type_support.cpp.em",
        "${CURRENT_DIR}/resource/dalidl_typesupport_fastrtps_cpp/msg__dalidl_typesupport_fastrtps_cpp.hpp.em",
        "${CURRENT_DIR}/resource/dalidl_typesupport_fastrtps_cpp/msg__type_support.cpp.em",
        "${CURRENT_DIR}/resource/dalidl_typesupport_fastrtps_cpp/srv__dalidl_typesupport_fastrtps_cpp.hpp.em",
        "${CURRENT_DIR}/resource/dalidl_typesupport_fastrtps_cpp/srv__type_support.cpp.em",
    ]
}

dalidl_typesupport_introspection_cpp_arg_dict = {
    "package_name": "${PKG_NAME}",
    "output_dir": "${CURRENT_DIR}/build/${PKG_NAME}/dalidl_typesupport_introspection_cpp/${PKG_NAME}",
    "template_dir": "${CURRENT_DIR}/resource/dalidl_typesupport_introspection_cpp",
    "idl_tuples": [],
    "target_dependencies": [
        "${CURRENT_DIR}/resource/dalidl_typesupport_introspection_cpp/idl__dalidl_typesupport_introspection_cpp.hpp.em",
        "${CURRENT_DIR}/resource/dalidl_typesupport_introspection_cpp/idl__type_support.cpp.em",
        "${CURRENT_DIR}/resource/dalidl_typesupport_introspection_cpp/msg__dalidl_typesupport_introspection_cpp.hpp.em",
        "${CURRENT_DIR}/resource/dalidl_typesupport_introspection_cpp/msg__type_support.cpp.em",
        "${CURRENT_DIR}/resource/dalidl_typesupport_introspection_cpp/srv__dalidl_typesupport_introspection_cpp.hpp.em",
        "${CURRENT_DIR}/resource/dalidl_typesupport_introspection_cpp/srv__type_support.cpp.em",
    ]
}

def code_gen(path):
    """
    use dalidl to generate msg type class files and typesupport files.

    Args:
        path: the path of a package, there must exist .idl file(s) in '${path}/msg'
    Returns:
        1: error occurs in code generating process.
        0: code generating succeed.
    Example:
        'python3 code_gen.py ~/my_interfaces'

        If you have the following directory structure:
        mj_interfaces
        └── msg
            ├── MsgA.idl
            └── MsgB.idl

    """
    success, pkg_name, pkg_parent_dir, idl_filenames = check_directory(path)
    if success:
        print("package name is: ", pkg_name)
    else:
        print("Error! no .idl file exist in msg directory.")
        return 1

    update_path(dalidl_generator_cpp_arg_dict, pkg_name, pkg_parent_dir, idl_filenames)
    update_path(dalidl_typesupport_cpp_arg_dict, pkg_name, pkg_parent_dir, idl_filenames)
    update_path(dalidl_typesupport_fastrtps_cpp_arg_dict, pkg_name, pkg_parent_dir, idl_filenames)
    update_path(dalidl_typesupport_introspection_cpp_arg_dict, pkg_name, pkg_parent_dir, idl_filenames)

    # import json
    # formatted_dict = json.dumps(dalidl_typesupport_cpp_arg_dict, indent=4)
    # print(formatted_dict)

    gen_files_generator = dalidl_generator_cpp_gen(dalidl_generator_cpp_arg_dict)
    if len(gen_files_generator) != 0:
        print("[dalidl_generator_cpp] generate code succeed.", )
    else:
        print("[dalidl_generator_cpp] generate code failed!" , end='\n', file=sys.stderr, flush=True)
        return 1

    gen_files_typesupport = dalidl_typesupport_cpp_gen(dalidl_typesupport_cpp_arg_dict, arg_typesupports)
    if len(gen_files_typesupport) != 0:
        print("[dalidl_typesupport_cpp] generate code succeed.")
    else:
        print("[dalidl_typesupport_cpp] generate code failed!" , end='\n', file=sys.stderr, flush=True)
        return 1
    
    gen_files_fastrtps = dalidl_typesupport_fastrtps_cpp_gen(dalidl_typesupport_fastrtps_cpp_arg_dict)
    if len(gen_files_fastrtps) != 0:
        print("[dalidl_typesupport_fastrtps_cpp] generate code succeed.")
    else:
        print("[dalidl_typesupport_fastrtps_cpp] generate code failed!" , end='\n', file=sys.stderr, flush=True)
        return 1


    gen_files_introspection = dalidl_typesupport_introspection_cpp_gen(dalidl_typesupport_introspection_cpp_arg_dict)
    if len(gen_files_introspection) != 0:
        print("[dalidl_typesupport_introspection_cpp] generate code succeed.")
    else:
        print("[dalidl_typesupport_introspection_cpp] generate code failed!" , end='\n', file=sys.stderr, flush=True)
        return 1

    return 0
    
    


